#!/usr/bin/python
#coding:utf-8
import os
import socket
import struct
import sys
import importlib
import threading
importlib.reload(sys)

packet_struct = struct.Struct('!IIIbb1024s')
feedback_struct = struct.Struct('II')
BUF_SIZE = 1024+14
FILE_SIZE = 1024
IP = "localhost"
CLIENT_IP="localhost"
CLIENT_PORT=7777
CLIENT_ADDRESS=(CLIENT_IP,CLIENT_PORT)
SERVER_PORT = 7776
RECV_BUF_SIZE = 1038 * 64
SEND_BUF_SIZE = 1038 * 64
FILE_NAME = "1234.jpg"

lock = threading.Lock()

buffer = []
print('Bind UDP on '+str(SERVER_PORT)+'...')

def server_thread(file, s, sender_address,data):

    while True:
        data,client_addr = s.recvfrom(RECV_BUF_SIZE)
        unpacked_data = packet_struct.unpack(data)
        file_data = unpacked_data[5]
        endflag = unpacked_data[4]
        header_size = unpacked_data[3]
        packet_size = unpacked_data[2]
        seq_received = unpacked_data[1]
        ack = unpacked_data[0]
        feedback_packet = feedback_struct.pack(ack,seq_received)
        s.sendto(feedback_packet,sender_address)
        if endflag != 1:
            file.seek(seq_received*1024)
            file.write(file_data)
        else:
            
            file.seek(seq_received*1024)
            file.write(file_data)
            break

def main():
    s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    s.setsockopt(socket.SOL_SOCKET,socket.SO_SNDBUF,SEND_BUF_SIZE)
    s.setsockopt(socket.SOL_SOCKET,socket.SO_RCVBUF,RECV_BUF_SIZE)
    s.bind(('localhost', SERVER_PORT))
    data, sender_address = s.recvfrom(RECV_BUF_SIZE)
    print(data.decode('utf-8')+' from '+str(sender_address[0])+":"+str(sender_address[1]))
    s.sendto("Receiver agree connection".encode('utf-8'), sender_address)
    
    data, sender_address = s.recvfrom(RECV_BUF_SIZE)
    print(data.decode('utf-8')+' from '+str(sender_address[0])+":"+str(sender_address[1]))
    FILE_NAME = data.decode('utf-8')[25:]
    file =  open(FILE_NAME, 'wb')
    server_thread(file, s, sender_address, data)
    file.close()
    print('\n开始中断连接')
# 中断连接，四次挥手
    data,server_addr = s.recvfrom(BUF_SIZE)

    data = 'Server allows disconnection'
    s.sendto(data.encode('utf-8'),sender_address)
    print(data)
    data = 'Server requests disconnection'
    s.sendto(data.encode('utf-8'),sender_address)
    print(data)
    data,server_addr = s.recvfrom(BUF_SIZE)
    print(data.decode('utf-8'))
    print('The connection between client and server has been interrupted')
    s.close()
    
if __name__ == "__main__":
    main()